package neuronet.client.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.ListModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import neuronet.client.ClientInfo;
import neuronet.client.NeuroNetClient;
import neuronet.server.ClientsTableItem;
import neuronet.server.NeuroNetServer;

import org.apache.log4j.Logger;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class ClientFrame extends javax.swing.JFrame implements ListSelectionListener {

    private static final long serialVersionUID = -2554289065163843621L;
    final static String CR = System.getProperty("line.separator");

    private JTextArea clientLogTextArea;
    private JTextArea clientInfoTextArea;
    private JTextArea receivedTextArea;
    private JTextArea sendTextArea;
    private JTextField serverPortTextField;
    private JButton configureButton;
    private JTextField clientTargetsTextField;
    private JTextField clientLastActiveTextField;
    private JTextField clientDataItemsTextField;
    private JTextField clientIDTextField;
    private JTextField serverIPTextField;
    private JButton loginButton;
    private JButton sendButton;
    private JButton logoutButton;
    private JButton receiveButton;
    private JButton exitjButton;
    private JButton createRandomButton;
    private JButton dosojButton;
    private JList clientsjList;
    private JLabel reciveLabel;
    private JLabel sendLabel;
    private JLabel serverIPLabel;
    private JLabel compnentsLabel;
    private JLabel clientLogLabel;
    private JLabel lastactiveLabel;
    private JLabel clientDataItemsLabel;
    private JLabel clientidLabel;
    private JLabel clieninfoLabel;
    private JLabel serverPortLabel;
    private JScrollPane clientLogScrollPane;
    private JScrollPane clientInfoScrollPane;
    private JScrollPane receivedScrollPane;
    private JScrollPane sendScrollPane;

    private JLabel clientTargetsLabel;

    // Indices of selected clients
    private int selClientIndices[];

    // the client
    private NeuroNetClient client;

    // LogOnFlag
    private boolean logonFlag = false;

    // log4j-Logger
    private static final Logger logger = Logger.getLogger(ClientFrame.class);

    //    /**
    //    * Auto-generated main method to display this JFrame
    //    */
    //    public static void main(String[] args)
    //    {
    //	SwingUtilities.invokeLater(new Runnable()
    //	{
    //
    //	    public void run()
    //	    {
    //		ClientFrame inst = new ClientFrame();
    //		inst.setLocationRelativeTo(null);
    //		inst.setVisible(true);
    //	    }
    //	});
    //    }

    public ClientFrame(NeuroNetClient client)
    {
	super();
	this.client = client;
	initGUI();
	initUpdater();
	this.setTitle("Neuro-Net Client: " + client.getClientID());
    }

    /**
     * Method for creation of an Updater to refresh GUI with new information from server.
     */
    private void initUpdater()
    {
	Timer timer;

	timer = new Timer();
	timer.schedule(new RemindTask(this), 5000, 5000);

    }

    class RemindTask extends TimerTask {

	ClientFrame client;

	public RemindTask(ClientFrame client)
	{
	    this.client = client;
	}

	public void run()
	{
	    //	    logger.info("Time's up!");
	    client.updateData();
	}
    }

    private void initGUI()
    {
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	try
	{
	    getContentPane().setLayout(null);
	    {
		clientLogTextArea = new JTextArea();
		clientLogTextArea.setPreferredSize(new java.awt.Dimension(877, 404));
		clientLogTextArea.setLayout(null);
		clientLogScrollPane = new JScrollPane(clientLogTextArea);
		clientLogScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		clientLogScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	    }
	    {
		sendTextArea = new JTextArea();
		//		sendTextArea.setPreferredSize(new java.awt.Dimension(877, 404));
		sendScrollPane = new JScrollPane(sendTextArea);
		sendScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		sendScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	    }
	    {
		receivedTextArea = new JTextArea();
		receivedTextArea.setLayout(null);
		//		sendTextArea.setPreferredSize(new java.awt.Dimension(877, 404));
		receivedScrollPane = new JScrollPane(receivedTextArea);
		receivedScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		receivedScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	    }
	    {
		clientInfoTextArea = new JTextArea();
		clientInfoTextArea.setPreferredSize(new java.awt.Dimension(339, 68));
		clientInfoScrollPane = new JScrollPane(clientInfoTextArea);
		clientInfoScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		clientInfoScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	    }
	    {
		createRandomButton = new JButton();
		createRandomButton.setText("Create Random");
		createRandomButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {
			logger.info("createRandomButton.actionPerformed, event=" + evt);
			createRandomData();
		    }

		});

	    }
	    {
		exitjButton = new JButton();
		exitjButton.setText("Exit");
		exitjButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {
			logger.info("exitjButton.actionPerformed, event=" + evt);
			// TODO: call Destructor of NeuroNetServer
			System.exit(0);
		    }
		});
	    }
	    {
		serverPortTextField = new JTextField();
	    }
	    {
		serverPortLabel = new JLabel();
		serverPortLabel.setText("Server Port");
	    }
	    {
		clieninfoLabel = new JLabel();
		clieninfoLabel.setText("Client Info");
	    }
	    {
		clientIDTextField = new JTextField();
		clientIDTextField.setText("Client" + System.currentTimeMillis());
	    }
	    {
		clientDataItemsTextField = new JTextField();
	    }
	    {
		clientLastActiveTextField = new JTextField();
	    }
	    {
		clientTargetsTextField = new JTextField();
	    }
	    {
		clientidLabel = new JLabel();
		clientidLabel.setText("Client ID");
	    }
	    {
		clientDataItemsLabel = new JLabel();
		clientDataItemsLabel.setText("Data Items");
	    }
	    {
		lastactiveLabel = new JLabel();
		lastactiveLabel.setText("Last Active");
	    }
	    {
		clientTargetsLabel = new JLabel();
		clientTargetsLabel.setText("Targets");
	    }
	    {
		clientLogLabel = new JLabel();
		clientLogLabel.setText("Client Log");
	    }
	    {
		ListModel clientsjListModel = new DefaultComboBoxModel(new String[] { "none" });
		clientsjList = new JList();
		clientsjList.setModel(clientsjListModel);
		clientsjList.addListSelectionListener(this);
	    }
	    {
		serverIPTextField = new JTextField();
		getContentPane().add(serverIPTextField);

	    }
	    {
		serverIPLabel = new JLabel();
		getContentPane().add(serverIPLabel);
		getContentPane().add(serverPortLabel);
		getContentPane().add(serverPortTextField);
		getContentPane().add(exitjButton);
		getContentPane().add(receivedScrollPane);
		getContentPane().add(clieninfoLabel);
		getContentPane().add(getDosojButton());
	    }
	    {
		compnentsLabel = new JLabel();
		compnentsLabel.setText("Components");
	    }
	    {
		receiveButton = new JButton();
		receiveButton.setText("Receive");
		receiveButton.setActionCommand("receive");
		receiveButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {
			logger.info("=================§§§§§§§§§§§§§§§§§§");
			logger.info("=================§§§§§§§§§§§§§§§§§§");
			logger.info("addButton.actionPerformed, event=" + evt);
			Vector<String> mess = client.getNewDataAsVector();
			for (String ret : mess)
			{
			    String old = receivedTextArea.getText();
			    receivedTextArea.setText(old + CR + ret);
			}
			receivedTextArea.setCaretPosition(receivedTextArea.getText().length());

			logger.info("=================§§§§§§§§§§§§§§§§§§");
			logger.info("=================§§§§§§§§§§§§§§§§§§");
		    }
		});
	    }
	    {
		logoutButton = new JButton();
		logoutButton.setText("Logout");
		getContentPane().add(logoutButton);
		getContentPane().add(clientLastActiveTextField);
		getContentPane().add(getConfigureButton());
		getContentPane().add(lastactiveLabel);
		getContentPane().add(clientInfoScrollPane);
		getContentPane().add(getReciveLabel());
		getContentPane().add(sendScrollPane);
		getContentPane().add(receiveButton);
		getContentPane().add(clientTargetsTextField);
		getContentPane().add(clientTargetsLabel);

		logoutButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {
			logger.info("logoutButton.actionPerformed, event=" + evt);
			logonFlag = !client.logoffClient();
		    }
		});
	    }
	    {
		sendButton = new JButton();
		getContentPane().add(sendButton);
		getContentPane().add(clientDataItemsTextField);
		getContentPane().add(clientDataItemsLabel);
		getContentPane().add(clientsjList);
		getContentPane().add(createRandomButton);
		getContentPane().add(getSendLabel());
		sendButton.setText("Send");
		sendButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {

			logger.info("'''''''##########");
			logger.info("'''''''##########");

			logger.info("sendButton.actionPerformed, event=" + evt);
			String ret = client.sendDataString(sendTextArea.getText());
			String old = sendTextArea.getText();
			sendTextArea.setText(old + CR + "Status:" + ret);
			sendTextArea.setCaretPosition(sendTextArea.getText().length());

			logger.info("'''''''##########");
			logger.info("'''''''##########");
		    }
		});
	    }
	    {
		loginButton = new JButton();
		getContentPane().add(loginButton);
		getContentPane().add(clientIDTextField);
		getContentPane().add(clientidLabel);
		getContentPane().add(compnentsLabel);
		getContentPane().add(clientLogLabel);
		getContentPane().add(clientLogScrollPane);
		serverIPLabel.setText("Server IP");
		loginButton.setText("Login");

		loginButton.addActionListener(new ActionListener()
		{

		    public void actionPerformed(ActionEvent evt)
		    {
			logger.info("loginButton.actionPerformed, event=" + evt);
			String serverip = serverIPTextField.getText();
			String serverpo = serverPortTextField.getText();
			int serverport = 0;
			try
			{
			    serverport = Integer.valueOf(serverpo);
			}
			catch (NumberFormatException e)
			{
			    serverPortTextField.setText("Illegal Port");
			    serverpo = "";
			    e.printStackTrace();
			}
			if (serverip.length() > 0 && serverpo.length() > 0)
			    client.setServer(serverip, serverport);
			logonFlag = client.logonClient(clientIDTextField.getText(), clientInfoTextArea.getText());

			client.configureClient(clientDataItemsTextField.getText(), clientTargetsTextField.getText());
		    }
		});

	    }
	    {
		clientLastActiveTextField.setLayout(null);
		clientDataItemsTextField.setLayout(null);
		clientIDTextField.setLayout(null);
		clientTargetsTextField.setLayout(null);

		// set Labels
		sendLabel.setBounds(531, 26, 147, 16);
		reciveLabel.setBounds(531, 104, 156, 16);
		clientTargetsLabel.setBounds(165, 82, 82, 20);
		lastactiveLabel.setBounds(165, 113, 82, 20);
		clieninfoLabel.setBounds(165, 162, 60, 15);
		serverPortLabel.setBounds(247, 706, 71, 19);
		serverIPLabel.setBounds(12, 705, 62, 20);
		clientLogLabel.setBounds(12, 270, 77, 20);
		compnentsLabel.setBounds(12, 26, 109, 16);
		clientDataItemsLabel.setBounds(165, 52, 82, 20);
		clientidLabel.setBounds(165, 23, 79, 23);

		// set Buttons
		dosojButton.setBounds(335, 141, 84, 23);
		configureButton.setBounds(430, 112, 84, 23);
		receiveButton.setBounds(430, 81, 84, 23);
		logoutButton.setBounds(430, 141, 84, 23);
		sendButton.setBounds(430, 52, 84, 23);
		exitjButton.setBounds(419, 704, 84, 23);
		loginButton.setBounds(430, 23, 84, 23);
		createRandomButton.setBounds(687, 23, 96, 23);

		// Set Textfields
		serverIPTextField.setBounds(74, 704, 165, 23);
		clientTargetsTextField.setBounds(255, 81, 165, 23);
		clientLastActiveTextField.setBounds(255, 112, 165, 23);
		clientIDTextField.setBounds(255, 23, 165, 23);
		clientDataItemsTextField.setBounds(255, 52, 165, 23);
		serverPortTextField.setBounds(318, 704, 85, 23);

		// set ScrollPanes
		clientInfoScrollPane.setBounds(165, 183, 350, 84);
		sendScrollPane.setBounds(531, 52, 378, 46);
		clientLogScrollPane.setBounds(12, 296, 910, 402);
		receivedScrollPane.setBounds(531, 130, 378, 136);
		
		// set Lists
		clientsjList.setBounds(12, 52, 135, 215);
	    }
	    pack();
	    this.setSize(950, 777);
	}
	catch (Exception e)
	{
	    //add your error handling code here
	    e.printStackTrace();
	}
    }

    public void updateData()
    {
	clientLogTextArea.setEnabled(false);
	if (logonFlag)
	{
	    // activate / deactivate Textfields

	    serverIPTextField.setEditable(false);
	    serverPortTextField.setEditable(false);

	    clientTargetsTextField.setEditable(false);
	    clientInfoTextArea.setEditable(false);
	    clientDataItemsTextField.setEditable(false);
	    clientIDTextField.setEditable(false);

	    receivedTextArea.setEditable(false);
	    sendTextArea.setEditable(true);
	}
	else
	{
	    // activate / deactivate Textfields

	    serverIPTextField.setEditable(true);
	    serverPortTextField.setEditable(true);

	    clientTargetsTextField.setEditable(true);
	    clientInfoTextArea.setEditable(true);
	    clientDataItemsTextField.setEditable(true);
	    clientIDTextField.setEditable(true);

	    receivedTextArea.setEditable(false);
	    sendTextArea.setEditable(false);

	}
	clientLogTextArea.setEditable(false);
	clientLastActiveTextField.setEditable(false);

	logger.info(".");

	if (selClientIndices == null || selClientIndices.length == 0)
	    clientsjList.setListData(client.getClientsAsVector());

	ClientInfo serverInfo = client.getServerInfoObject();
	ClientInfo clientInfo = client.getClientInfoObject(client.getClientID());

	//	clientLogTextArea.setText(serverInfo.getLog());
	serverIPTextField.setText(serverInfo.getIP());
	serverPortTextField.setText(serverInfo.getPort());

	clientLastActiveTextField.setText(clientInfo.getLast());

	if (!(clientInfo.getPort().length() == 0) && !(clientInfo.getPort().equals("-1")))
	{
	    clientTargetsTextField.setText(clientInfo.getTargets().toString());

	    ListModel targetListModel = new DefaultComboBoxModel(clientInfo.getTargets().toString().split(","));
	    //	// Targetlist deactivated
	    //	    targetList.setModel(targetListModel);
	}
	if (!(clientInfo.getInfo().length() == 0) && !(clientInfo.getInfo().equals("-1")))
	    clientInfoTextArea.setText(clientInfo.getInfo());

	if (!(clientInfo.getIP().length() == 0) && !(clientInfo.getIP().equals("-1")))
	    clientDataItemsTextField.setText(clientInfo.getDataItems().toString());

	if (!(clientInfo.getID().length() == 0) && !(clientInfo.getID().equals("-1")))
	    clientIDTextField.setText(clientInfo.getID());

	logger.info("..");

    }

    public void addLogMessage(String mess)
    {
	String text = clientLogTextArea.getText();
	text += " \n\r " + mess;
	clientLogTextArea.setText(text);
	clientLogTextArea.setCaretPosition(text.length());
    }

    public void setClientID(String clientid)
    {
	this.clientIDTextField.setText(clientid);
    }

    @Override
    public void valueChanged(ListSelectionEvent e)
    {
	logger.info("First index: " + e.getFirstIndex());
	logger.info("Last index: " + e.getLastIndex());
	boolean adjust = e.getValueIsAdjusting();
	logger.info("Adjusting? " + adjust);
	if (!adjust)
	{
	    JList list = (JList) e.getSource();
	    selClientIndices = list.getSelectedIndices();
	    Object selectionValues[] = list.getSelectedValues();
	    for (int i = 0, n = selClientIndices.length; i < n; i++)
	    {
		if (i == 0)
		{
		    logger.info("  Selections: ");
		}
		logger.info(selClientIndices[i] + "/" + selectionValues[i] + " ");
	    }
	}
	if (selClientIndices != null && selClientIndices.length > 0)
	{
	    ClientsTableItem lastIndexClient = NeuroNetServer.getClientItem((String) clientsjList.getSelectedValues()[clientsjList.getSelectedValues().length - 1]);
	    if (lastIndexClient != null)
	    {
		clientIDTextField.setText(lastIndexClient.getClientID());
		clientInfoTextArea.setText(lastIndexClient.getClientInfo());
		clientLastActiveTextField.setText(lastIndexClient.getClientLast());
		clientDataItemsLabel.setText(lastIndexClient.getClientIP());
		clientTargetsTextField.setText(lastIndexClient.getClientPort());
	    }
	}
	//	else
	//	    {
	//	    clientidTextField.setText("");
	//	    clientinfoTextField.setText("");
	//	    }
    }

    public String getTargets()
    {
	String target = clientTargetsTextField.getText();
	return target;
    }

    public String getDataItems()
    {
	String data = clientDataItemsTextField.getText();
	return data;
    }

    public void setServerURL(String serverURL)
    {
	serverIPTextField.setText(serverURL);
    }

    public void setServerPort(int serverPort)
    {
	serverPortTextField.setText(serverPort + "");
    }

    public void setDataItems(String dataitems)
    {
	clientDataItemsTextField.setText(dataitems);
    }

    public void setTargets(String targets)
    {
	clientTargetsTextField.setText(targets);
    }

    private JLabel getSendLabel()
    {
	if (sendLabel == null)
	{
	    sendLabel = new JLabel();
	    sendLabel.setText("Send Message");
	}
	return sendLabel;
    }

    private JLabel getReciveLabel()
    {
	if (reciveLabel == null)
	{
	    reciveLabel = new JLabel();
	    reciveLabel.setText("Recived Messages");
	}
	return reciveLabel;
    }

    private JButton getDosojButton()
    {
	if (dosojButton == null)
	{
	    dosojButton = new JButton();
	    dosojButton.setText("DoSo");
	}
	return dosojButton;
    }

    public void createRandomData()
    {
	int no = clientDataItemsTextField.getText().split(",").length;
	String dataStr = "type:senddata clientid:" + client.getClientID() + " clientkey:" + client.getClientKey() + " data[";
	Random r = new Random();
	for (int i = 0; i < no; i++)
	{
	    dataStr += r.nextInt(10010);
	    if (i < no - 1)
		dataStr += ",";
	}
	dataStr += "] end:end";

	sendTextArea.setText(dataStr);
    }

    private JButton getConfigureButton()
    {
	if (configureButton == null)
	{
	    configureButton = new JButton();
	    configureButton.setText("Config");
	}
	return configureButton;
    }
}
